/**
	License:		Artistic license 2.0 (see license.txt, also available online at http://www.perlfoundation.org/artistic_license_2_0)
	Authors:		OrbitalLab (http://www.orbitallab.ru/moonglide/), 2007-2009

	File:			GuiCursor.d
	Description:	basic cursor stuff
	Date:			17.05.2008 by Digited
*/
module moonglide.gui.GuiCursor;

import
	moonglide.io.LogSystem,
	moonglide.math.MoonMath,
	moonglide.util.MoonUtil,

	moonglide.core.Controllers,
	moonglide.core.Events,

	moonglide.core.engobjects.EngRawData;

//================================================================
/// special gui class: cursor
//================================================================
class CGuiCursor : public CEngRawData
{
	protected:
		Size2ui			_viewportSize,
						_position,
						_lastPosition;

		char[]			_currentState;		/// key of current index of both state and its image

	public:
		bool			freezed;			/// movable flag

		uint[ char[] ]	states;				/// states array: id's of states

		char[]			State()		{ return _currentState; }
		uint			StateCode()	{ return states[_currentState]; }

		override bool	isPointAbove( Size2ui p ) { return false; }

		//============================================================
		/// set cursor state. Be careful about them!
		//============================================================
		void State( char[] newState )
		{
			if(( newState in states ) == null )
				states[ newState] = states.length;

			_currentState = newState;
		}

		//================================================================
		/// position stuff
		//================================================================
		void CheckBounds()
		{
			if( _position.x < 0 )
				_position.x = 0;

			if( _position.x >= _viewportSize.x )
				_position.x = _viewportSize.x - 1;

			if( _position.y < 0 )
				_position.y = 0;

			if( _position.y >= _viewportSize.y )
				_position.y = _viewportSize.y - 1;
		}

		void SetPosition( Point2i newpos )
		{
			if( freezed )
				return;

			_lastPosition = _position;
			_position.set( newpos.x, newpos.y );
			CheckBounds();
		}

		void Move()
		{
			if( freezed )
				return;

			_lastPosition = _position;
			_position.x += mouseState.x;
			_position.y += mouseState.y;

			CheckBounds();
		}

		///ditto
		Size2ui Position() { return _position; }
		Size2ui LastPosition() { return _lastPosition; }

		///ditto
		void viewportSize( Size2ui newsize )
		{
			_viewportSize = newsize;
			CheckBounds();
		}

		Size2ui viewportSize() { return _viewportSize; }

		bool IsPointAbove( Point2i p ) { return false; }

		//================================================================
		/// input
		//================================================================
		override void onEventCallback( CEvent event, IEventGenerator sender )
		{
			switch( event.type )
			{
				case eeventtype.program:
					switch( event.subtype )
					{
						case eprogramevent.command:
							if(( "freezed" in event.bools ) != null )
								freezed = event.bools["freeze"];

							if(( "state" in event.strings ) != null )
								State = event.strings["state"];

							return;

						default: break;
					}
					break;

				default: break;
			}
		}

		override void onEventReceive( CEvent event, IEventSender sender )
		{
			onEventCallback( event, this );
		}

		//================================================================
		/// constructor & destructor stuff
		//================================================================
		this( char[] id, Size2ui viewport )
		in
		{
			moonAssert( viewport.x == 0 && viewport.y == 0, "viewport == 0", __FILE__, __LINE__ );
		}
		body
		{
			super( id );
			_viewportSize = viewport;
		}


		~this()
		{
			states = null;
		}
}
